iT邦幫忙

2023 iThome 鐵人賽

DAY 20
1
WordPress

從 0 到 100:WordPress 開發者的實戰手冊系列 第 20

Day 20 - 使用 Rewrite API 設計客制化網址路由

  • 分享至 

  • xImage
  •  

WordPress 的 Rewrite API 是專為網址靜態化設計的,它把含有 ?= 的網址參數去除,轉換成像是靜態網頁般的網址結構。在 WordPress 的世界中,稱作永久連結 (permalink)。

在早期的搜尋引擎對於這樣的靜態網址十分友好,對搜尋結果的排名有些許幫助,於是 WordPress 在 2005 年 發布的 1.5 版引進了 Rewrite API,提供了一套靈活的 URL 重寫系統,允許開發者和使用者自定義他們的網站的永久連結結構。

網址改寫靜態化
圖:網址改寫靜態化

現今這樣的靜態網址已經對 SEO 沒什麼幫助,原因之一是藏在網址上的關鍵字被濫用,其二是大家都是靜態化的網址,都一樣,自然沒優劣之分,但靜態網址比起重寫前的動態網址來得較短、好記憶,有助於使用者更好地理解網址結構。

運作原理

收到請求到重寫 URL 流程
圖:收到請求到重寫 URL 流程

  • 讀取與解析: 伺服器收到請求,會讀取 .htaccess 檔案 (Apache) 或設定檔案 (Nginx) 中的 rewrite 規則,並解析請求的 URL。

  • 匹配規則: 接著,系統會從上到下依次嘗試匹配設定的 rewrite 規則。一旦找到匹配的規則,系統將重寫 URL 或終止進一步的規則處理。

  • 查詢與載入: 之後,WordPress 根據解析結果生成對應的查詢。根據這個查詢,載入並顯示對應的頁面或文章。

自定義 Rewrite 規則

開始自定義網址改寫規則的範例之前,先認識一下 WordPress 的 WP_Rewrite 類別。

它在 wp-includes/rewrite.php 中被定義為一個單一實例的全域變數 $wp_rewrite,並在 wp-settings.php 中初始化,用於管理永久連結功能的重寫規則。

相關函式

我們可以直接使用 $wp_rewrite 這個全域變數,並使用它的方法,不過 WordPress 提供了相關的函式來包裝 WP_Rewrite 物件使用,這樣可以讓程式碼看起來比較整潔,更好使用。

函式:add_rewrite_rule

add_rewrite_rule( $regex, $redirect, $after );

用於新增自定義的 URL 重寫規則,將美化的 URL 映射到 WordPress 查詢變數。

  • $regex 匹配 URL 的正則表示式。
  • $redirect 匹配到的 URL 將要重定向到的目標。
  • $after 控制新規則將被加到重寫規則陣列的哪個部分。

關於第三個參數 $after 可以接收兩個值:

  • top:你的自定規則將被排在 WordPress的所有內建規則的最前面。WordPress 在解析 URL 時會首先考慮自定規則。在多數情況下,自定義規則能夠優先於 WordPress 的內建規則的話,才不會被內建的規則覆蓋掉或者被忽略。

  • bottom:自定的規則將被排在所有內建規則的最後面,通常是為了讓規則只在內建規則無法套用的情況下才生效,才會設定為這個值。

範例

add_rewrite_rule 範例程式碼
圖:add_rewrite_rule 範例程式碼

第 7 行:我們的主角,add_rewrite_rule 函式。
第 8 行:第一個參數,為定義靜態網址規則。
第 9 行:第二個參數,映射到原始的 PHP 動態網址的規則。
第 10 行:第三個參數,設為 top,讓我們的自定義的規則高於內建的頁面規則。如果設為 bottom 的話,此規則會失效而 404。

函式:add_rewrite_tag

add_rewrite_tag( $tag, $regex, $query );

建立自定的查詢變數並用於 URL 重寫規則,通常與 add_rewrite_rule 結合使用。

  • $tag:格式為 %my_var% 的字串,定義了查詢變數的名稱。
  • $regex:匹配查詢的變數值的正則表示式。
  • $query (可選):定義如何在查詢中使用這個變數。

add_rewrite_tag 範例程式碼
圖:add_rewrite_tag 範例程式碼

第 7 行:我們的主角,add_rewrite_tag 函式,第一個參數定義變數名稱,第二個參數為正規表示式比對匹配的值。
第 8 行:我們的男配角,add_rewrite_rule 函式。
第 9 行:第一個參數,為定義靜態網址規則。
第 10 行:第二個參數,映射到原始的 PHP 動態網址的規則,my_var 是我們剛剛在第 7 行定義的變數名稱。

取得變數的值

add_action( 'template_redirect', function () {
    $var = get_query_var('my_var');
} );

接下來,我們可以使用 get_query_var 函式取得該變數的值,不過要註冊在 template_redirect 鉤點,待 WP_Query 類別實例化之後才生效。

函式:add_rewrite_endpoint

add_rewrite_endpoint( $name, $places, $query_var );

為 WordPress 的重寫規則系統新增新的端點,這些端點可用於 URL 中的任何位置。

  • $name:新端點的名稱,這個名稱將會成為查詢變數的名稱,同時也將用於 URL 結構中。
  • $places: 一個位元遮罩 (bitmask),用來定義端點在哪些位置是有效的。WordPress 定義了幾個常數來幫助設定這個值,包括 EP_PERMALINKEP_ATTACHMENTEP_ROOTEP_CATEGORIES 等,從變數的字面上看可以得知是用在那些種類的頁面。
  • $query_var (可選):將 $name 作為查詢變數的名稱添加到查詢變數列表中,或者使用自定義的查詢變數名稱。基本上不用理會這個值,預設值為 true

範例

add_rewrite_endpoint 範例程式碼
圖:add_rewrite_endpoint 範例程式碼

這個例子中,add_my_endpoint 函式加入了一個名為 api 的新端點,並通過 EP_PAGES 常數指定這個端點只在頁面類型的 URL 中有效。當這個端點被加入後,它將可以用作查詢變數,並且可以在 URL 中像這樣使用:

http://yoursite.com/sample-page/api/1

在這個 URL 中, api 是新增的端點,而 1api 端點的值。接著我們可以在佈景主題的範本檔案中,或者在編寫外掛的時候,註冊到 template_redirect 之後的鉤點,透過以下方式取值。

$api = get_query_var( 'api' );
// 1

函式:add_permastruct

add_permastruct( $name, $struct, $args );

定義新的永久連結結構,允許開發者定義並 URL 結構模式。

  • $name :Permastruct 的名稱,它在內部用來作為識別碼。
  • $struct:URL 結構。包含用百分比符號 (%) 括起來的重寫標籤。
  • $args (可選):一個參數陣列。

add_permastruct 範例程式碼
圖:add_permastruct 範例程式碼

第 10 行:我們的主角,add_permastruct 函式,第一個參數定義識別名稱。
第 11 行:第二個參數為正規表示式比對匹配的值,匹配的標籤需先定義,因此第 7 行及第 8 行定義了這兩個查詢變數標籤。
第 13 行:可選參數,請參考以下表格。

可選參數

參數 型別 預設值 說明
with_front bool true URL 是否在「前端」有基底。例如,如果你的永久連結結構是 /blog/%postname%/,並且此值設為 true 則結構會是 /blog/my_custom_structure
ep_mask int EP_PERMALINK 端點 (mask) 用來描述支持的端點類型。如果沒有設定,將使用預設的 EP_PERMALINK。
paged bool true 是否允許分頁。
feed bool true 是否允許 feed 端點。
forcomments bool false 是否允許迴響分頁端點。
walk_dirs bool true 是否 URL 中分層。
endpoints bool true 是否允許其他端點。

函式:remove_rewrite_tag

移除之前用 add_rewrite_tag 定義的查詢變數及其相關的重寫標籤。
這這個函式很不常用。如果你有用到它的情境歡迎留言分享喔。

保存路由設定

後台頁面 - 永久連結設定
圖:後台頁面 - 永久連結設定

當設計完我們的路由重寫規則後,必須保存設定,才能把這些資料寫回資料庫讓它生效。來到後台「設定」,「永久連結」設定頁面,下方的「儲存設定」按紐,按下即可。

函式:flush_rewrite_rules

另外一個更新路由設定的方法是使用 flush_rewrite_rules 這個函式,它的使用時機適合在「外掛啟用」的時刻,把我們外掛有用到的路由設定儲到資料庫去。

資料表 wp_options
圖:資料表 wp_options

由於這個函式會觸發清空、更新資料表 wp_optionsrewrite_rules 欄位,此欄位尺寸不小,加上更新資料表很耗能。如果把它註冊到每一頁都可觸發的鉤點,CPU 的負擔會很重,資料庫的 binlog 體積也會肥的很快速,小心使用!

總結

WordPress 的 Rewrite API 可以讓我們設定有特色的頁面專屬網址,藉由今天提到的五個相關函式,很方便地用來設計外掛功能的專屬頁面網址。

不過要特別注意,由於 WordPress 的路由規則是存在資料表中,並不是很直接地可以檢視它們的先後順序,因此在測試路由的時候要特別小心,以免覆蓋到現有功能所需要的功能頁面網址哦。


課後思考:

實務上,如果遇到外掛開發者會把 flush_rewrite_rules 之類會立即刷新資料庫資料的函式註冊到每一頁會觸發的鉤點,要怎麼發現?

前篇解答參考:

在設計權限的時候,最好的作法是採用「最小權限」原則,先賦予最小的權限,只給該角色任務需要的權限。另外,越高的權限,例如管理團隊內的權限,則限制 IP ,只能在公司網路登入,在外工作時則需透過 VPN 連線,達到最基本的安全管控。


上一篇
Day 19 - 詳解 WordPress 的使用者角色與權限控管
下一篇
Day 21 - 利用 WP_Query 類別來自定內容查詢
系列文
從 0 到 100:WordPress 開發者的實戰手冊30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言